﻿using System;
using System.Globalization;
using System.Linq;
using log4net;
using Xtensive.Storage;

namespace Sherwood.Content.DO.Model
{
    /// <summary>
    /// Represents a content item
    /// </summary>
    [HierarchyRoot]
    [Serializable]
    [Index("Client", "ReferenceId", Unique = true)]
    public class Record : Entity, IRecord
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(Record));

        public Record(Client client, string referenceId, string title)
        {
            if (client == null) throw new ArgumentNullException("client");
            if (string.IsNullOrEmpty(referenceId)) throw new ArgumentNullException("referenceId");

            DateCreated = DateTime.UtcNow;
            Client = client;
            ReferenceId = referenceId;
            Title = title;

            if (Log.IsDebugEnabled)
                Log.DebugFormat("Record {0} created for client {1}", title, client);
        }

        /// <inheritdoc/>
        [Field, Key]
        public Guid Id { get; private set; }

        /// <inheritdoc/>
        [Field(Indexed = true, Length = 512, Nullable = false)]
        public string ReferenceId { get; private set; }

        /// <inheritdoc/>
        [Field(Indexed = true, Length = 512)]
        public string CultureInvariantReferenceId { get; set; }

        /// <summary>
        /// The source client of this record
        /// </summary>
        [Field]
        public Client Client { get; private set; }

        /// <inheritdoc/>
        [Field]
        public bool IsDeleted { get; set; }

        /// <inheritdoc/>
        [Field]
        public DateTime DateCreated { get; private set; }

        /// <inheritdoc/>
        [Field]
        public DateTime? DateModified { get; set; }

        /// <inheritdoc/>
        [Field]
        public DateTime? DateIndexed { get; set; }

        protected override void OnSetFieldValue(Xtensive.Storage.Model.FieldInfo field, object oldValue, object newValue)
        {
            switch (field.Name)
            {
                case "Title":
                case "CultureInvariantReferenceId":
                case "Description":
                case "CultureName":
                    DateModified = DateTime.UtcNow;
                    break;
            }

            base.OnSetFieldValue(field, oldValue, newValue);
        }

        /// <inheritdoc/>
        [Field(Length = 512)]
        public string Title { get; set; }

        /// <inheritdoc/>
        [Field(Length = 4096)]
        public string Description { get; set; }

        /// <inheritdoc/>
        [Field(Length = 10)]
        public string CultureName { get; set; }

        /// <inheritdoc/>
        [Field(Length = 10)]
        public string LanguageCode { get; set; }

        /// <summary>
        /// A collection of all metas that apply to this record
        /// </summary>
        [Field, Association(PairTo = "Record", OnOwnerRemove = OnRemoveAction.Cascade, OnTargetRemove = OnRemoveAction.Clear)]
        public EntitySet<Meta> Metas { get; private set; }
        
        IQueryable<IMeta> IRecord.Metas
        {
            get { return Metas; }
        }
        IClient IRecord.Client
        {
            get { return Client; }
        }

        protected override void OnRemove()
        {
            base.OnRemove();

            if (Log.IsDebugEnabled)
                Log.DebugFormat("Record {0} deleted", Id);
        }
    }
}